package com.rapida.net;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.GZIPInputStream;

import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.http.protocol.HTTP;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

public class HTTPClient {
	private static final String TAG = "HTTPClient";
	public static final byte GET_METHOD = 0x00;
	public static final byte POST_METHOD = 0x01;

	public static final String UTF_8 = "UTF-8";

	public final static int TIMEOUT_CONNECTION = 20000;
	public final static int TIMEOUT_SOCKET = 20000;

	private static String appUserAgent;
	private HttpClient _httpClient;
	private HttpMethod _method;

	private HttpClient getHttpClient() {
		HttpClient httpClient = new HttpClient();
		httpClient.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);
		httpClient.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
				new DefaultHttpMethodRetryHandler());
		httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(TIMEOUT_CONNECTION);
		httpClient.getHttpConnectionManager().getParams().setSoTimeout(TIMEOUT_SOCKET);
		httpClient.getParams().setContentCharset(UTF_8);
		return httpClient;
	}

	private InputStream getResponseBodyStream() {
		InputStream responseBodyStream = null;

		try {
			int statusCode = _httpClient.executeMethod(_method);
			if (statusCode != HttpStatus.SC_OK) {
			}
			Header header = _method.getResponseHeader("Content-Encoding");
			if (header != null && header.getValue().equalsIgnoreCase("gzip")) {
				responseBodyStream = new GZIPInputStream(_method.getResponseBodyAsStream());
			} else {
				responseBodyStream = new ByteArrayInputStream(_method.getResponseBody());
			}
		} catch (HttpException e) {
			Log.d(TAG, "getResponseBodyStream() HttpException");
		} catch (IOException e) {
			Log.d(TAG, "getResponseBodyStream() IOException");
		} finally {
			releaseConnection();
		}

		return responseBodyStream;
	}

	private void releaseConnection() {
		if (_method != null) {
			_method.releaseConnection();
		}
		if (_httpClient != null) {
			_httpClient = null;
		}
	}

	private static HttpMethod getMethod(byte methodType, String url, String userAgent) {
		HttpMethod httpMethod = null;
		switch (methodType) {
		case GET_METHOD:
			httpMethod = new GetMethod(url);
			break;
		case POST_METHOD:
			httpMethod = new PostMethod(url);
			break;
		}
		httpMethod.getParams().setSoTimeout(TIMEOUT_SOCKET);
		httpMethod.setRequestHeader("Accept-Encoding", "gzip,deflate,sdch");
		httpMethod.setRequestHeader("Accept-Language", "zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4");
		httpMethod.setRequestHeader("Connection", "Keep-Alive");
		httpMethod.setRequestHeader(HTTP.USER_AGENT, userAgent);
		return httpMethod;
	}

	private static String getUserAgent() {
		if (appUserAgent == null || appUserAgent == "") {
			StringBuilder ua = new StringBuilder();
			ua.append("/Android");
			ua.append("/" + android.os.Build.VERSION.RELEASE);
			ua.append("/" + android.os.Build.MODEL);
			appUserAgent = ua.toString();
		}
		return appUserAgent;
	}

	public Bitmap getBitmap() {
		Bitmap bitmap = null;
		InputStream inStream = getResponseBodyStream();
		bitmap = BitmapFactory.decodeStream(inStream);
		try {
			inStream.close();
		} catch (IOException e) {
			Log.d(TAG, "getBitmap() IOException");
		}
		return bitmap;
	}

	public HTTPClient requestUrl(byte methodType, String url) {
		_httpClient = getHttpClient();
		_method = getMethod(methodType, url, getUserAgent());
		return this;
	}

	public static HTTPClient getHTTPClient() {
		return new HTTPClient();
	}
}
